package cn.by.wms.mybatisx;

import cn.by.wms.entity.BaseEntity;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.smart.core.util.UserSessionContext;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
@Intercepts({
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class})
})
@Slf4j
public class StatementHandlerPlugin implements Interceptor {

    @Autowired
    private  MonitorProperties monitorProperties;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();
        net.sf.jsqlparser.statement.Statement statement = CCJSqlParserUtil.parse(sql);
        if(statement instanceof Insert){
            Insert  insertStatement = (Insert)statement;
            insertHandler(insertStatement);

        } else if(statement instanceof Update){
            Update  updateStatement = (Update)statement;
            updateHandler(updateStatement);

        }
        return invocation.proceed();
    }

    private static  final String dingdingUrl = "https://oapi.dingtalk.com/robot/send?access_token=ac10ba493e58e14ea21f37e1f84344b18612531df8af845c07e3a6945c99a981";
    private void  sendDingDing(String tableName){
        JSONObject json1 = JSONUtil.createObj();
        json1.putOpt("msgtype","text");
        String msg = StrUtil.format("告警:{}, 更改了表：{}", UserSessionContext.get().getNickName(),tableName);
        json1.putOpt("text",JSONUtil.createObj().putOpt("content",msg));
        JSONArray array = JSONUtil.createArray();
        array.add("15237666940");
        array.add("18537866710");
        json1.putOpt("at",JSONUtil.createObj().putOpt("isAtAll",false).putOpt("atMobiles",array));
        String json = JSONUtil.toJsonStr(json1);
        String result = HttpRequest.post(dingdingUrl)
                .body(json)
                .execute().body();

        JSONObject jsonObject = JSONUtil.parseObj(result);
        Object errcode = jsonObject.get("errcode");
        if(errcode.equals(0)){
            log.debug("发送钉钉成功");
        }else{
            log.error("发送钉钉失败：{}",jsonObject.get("errmsg"));
        }

    }

    private   void insertHandler(Insert insertStatement){
        String tableName = insertStatement.getTable().getName();

        List<Map<String, List<String>>> tables = monitorProperties.getTables();

        for (Map<String, List<String>> map : tables) {
            boolean b = map.keySet().contains(tableName);
            if(b){
                log.debug("开始报警");
                sendDingDing(tableName);
                break;
            }
        }
    }
    private  void updateHandler(Update updateStatement){

        String tableName = updateStatement.getTable().getName();

        List<Map<String, List<String>>> tables = monitorProperties.getTables();

        for (Map<String, List<String>> map : tables) {
            List<String> monitorColumns = map.get(tableName);
            if(ObjUtil.isNotEmpty(monitorColumns)){
                ArrayList<UpdateSet> updateSets = updateStatement.getUpdateSets();
                for (UpdateSet item : updateSets) {
                    boolean b = monitorColumns.contains(item.getColumns().get(0).getColumnName());
                    if (b) {
                        log.debug("开始报警");
                        sendDingDing(tableName);
                        break;
                    }
                }

            }
        }
    }
}
